#include "detk/file.h"
#include "deds/bool.h"
#include <stdlib.h>
#include <assert.h>

static unsigned mx__szWildMatch7(const char *pat, const char *str)
{
	const char *s, *p;
	unsigned star = false;

  loopStart:
	for (s = str, p = pat; *s; ++s, ++p) {
		switch (*p) {
		case '?':
			if (*s == '.')
				goto starCheck;
			break;
		case '*':
			star = true;
			str = s, pat = p;
			do {
				++pat;
			}
			while (*pat == '*');
			if (!*pat)
				return true;
			goto loopStart;
		default:
			if (*s != *p)
				goto starCheck;
			break;
		}
	}
	while (*p == '*')
		++p;
	return (!*p);

  starCheck:
	if (!star)
		return false;
	str++;
	goto loopStart;
}

/** This function return non-zero if a filename matches a given pattern.  
Patterns match '*' to one or more characters and '?' to a single character. */
unsigned mx_filename_match(const char *p, const char *t)
{
	int i = 0;
	unsigned found = false;
	char *current = 0;

	assert(p);
	assert(t);

	while (p[i]) {
		int offset = 0;

		/** Multiple patterns can be matched by sepaarating them
            with ';' characters. */
		while (p[i] == ';')
			++i;

		if (!current)
			current = malloc(FILENAME_MAX);

		/* Extract the first pattern to match */
		while ((p[i]) && (p[i] != ';'))
			current[offset++] = p[i++];
		current[offset] = '\0';

/**author Filename matching code taken with permission from the very nice
   webpage of Alessandro Cantaore
   <a href="http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html">
   http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html</a>
*/
		if (mx__szWildMatch7(current, t)) {
			found = true;
			goto done;
		}
	}
  done:
	if (current)
		free(current);

	return found;
}
